/*
 * ThreadPool.cpp
 *
 *  Created on: 2015年11月24日
 */
#include "ThreadPool.h"
#include <chrono>
#include <stdexcept>
namespace gdface{
ThreadPool::ThreadPool(size_t concurrency, bool force)
    : concurrency(concurrency),stop(false)
{
    for(size_t i = 0;i<this->concurrency;++i)
        workers.emplace_back(
            [this]
            {
                for(;;)
                {
                    std::function<void()> task;

                    {
                        std::unique_lock<std::mutex> lock(this->queue_mutex);
                        this->condition.wait_for(lock, std::chrono::milliseconds(100),
                            [this] { return this->stop || !this->tasks.empty(); });
                        if (this->stop)
                        {
                            if (this->force)
                                return;
                            else if (this->tasks.empty())
                                return;
                        }
                        else if (this->tasks.empty())
                            continue;
                        task = std::move(this->tasks.front());
                        this->tasks.pop();
                    }

                    task();
                }
            }
        );
}

// the destructor joins all threads
ThreadPool::~ThreadPool()
{
    {
        std::unique_lock<std::mutex> lock(queue_mutex);
        stop = true;
    }
    // remove,because the code will cause deadlock while dynamic library unload
    //condition.notify_all();
    for(std::thread &worker: workers)
        worker.join();
}

} /* namespace gdface */



